﻿global using WXWorkSvc.Common.Data;

using Microsoft.AspNetCore.Http;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Logging;

using System.Net.Http.Json;
using System.Security.Claims;
using System.Text;
using System.Web;

using WXWorkSvc.Common.Extensions;
using WXWorkSvc.Common.Models;

namespace WXWorkSvc.Private;

public class WXWork
{
    private readonly HttpClient _HC;
    private readonly IHttpContextAccessor _Accessor;
    private readonly ILogger<WXWork> _Logger;
    private readonly IServiceProvider _ServiceProvider;
    private readonly WXWorkConfig _Config;
    public WXWork(HttpClient hc, WXWorkConfig config, IHttpContextAccessor acc, ILogger<WXWork> logger, IServiceProvider provider)
    {
        _HC = hc;
        _Config = config;
        _HC.BaseAddress = new Uri("https://qyapi.weixin.qq.com");
        _Accessor = acc;
        _Logger = logger;
        _ServiceProvider = provider;
    }

    public string GetOAuthUrl(HttpRequest request, string state)
    {
        var redirectUri = HttpUtility.UrlEncode($"{_Config.ApplicationUrl}/cb/{Convert.ToBase64String(Encoding.UTF8.GetBytes(request.Host.ToString()))}");

        if (request.IsWXBrowse())
        {
            return $"https://open.weixin.qq.com/connect/oauth2/authorize?appid={_Config.CorpId}&redirect_uri={redirectUri}&response_type=code&scope=snsapi_base&state={state}#wechat_redirect";
        }
        else
        {
            return $"https://login.work.weixin.qq.com/wwlogin/sso/login?login_type=CorpApp&appid={_Config.CorpId}&redirect_uri={redirectUri}&state={state}&agentid={_Config.AgentId}";
        }
    }


    /// <summary>
    /// 获取通讯录人员信息
    /// </summary>
    /// <param name="userId"></param>
    /// <returns></returns>
    public async Task<ResponseUser> GetUserAsync(string userId)
    {

        var ret = await _HC.GetFromJsonAsync<ResponseUser>($"cgi-bin/user/get?access_token={await GetAccessTokenAsync()}&userid={userId}");
        ret.Valid();
        return ret!;
    }

    public async Task SendTextMessageAsync(string? userIds, string message)
    {
        if (string.IsNullOrEmpty(userIds))
            return;
        if (userIds.Split('|').Where(ii => !string.IsNullOrEmpty(ii)).Count() == 0)
            return;

        await _HC.PostAsJsonAsync($"cgi-bin/message/send?access_token={await GetAccessTokenAsync()}", new
        {
            touser = userIds,
            agentid = _Config.AgentId,
            msgtype = "text",
            text = new
            {
                content = message
            }
        });
    }
    /// <summary>
    /// 
    /// </summary>
    /// <param name="userIds">指定接收消息的成员，成员ID列表（多个接收者用‘|’分隔，最多支持1000个）。    特殊情况：指定为"@all"，则向该企业应用的全部成员发送</param>
    /// <param name="message">markdown内容，最长不超过2048个字节，必须是utf8编码</param>
    /// <returns></returns>
    public async Task SendMDMessageAsync(string? userIds, string message)
    {

        if (string.IsNullOrEmpty(userIds))
            return;
        if (userIds.Split('|').Where(ii => !string.IsNullOrEmpty(ii)).Count() == 0)
            return;

        await _HC.PostAsJsonAsync($"cgi-bin/message/send?access_token={await GetAccessTokenAsync()}", new
        {
            touser = userIds,
            agentid = _Config.AgentId,
            msgtype = "markdown",
            markdown = new
            {
                content = message
            }
        });
    }




    public async Task<ResponseOAuthUser> GetOAuthUserAsync(string code)
    {
        var ret = await _HC.GetFromJsonAsync<ResponseOAuthUser>($"cgi-bin/user/getuserinfo?access_token={await GetAccessTokenAsync()}&code={code}");
        ret.Valid();
        return ret!;
    }
    private async Task<string> GetAccessTokenAsync()
    {
        using var db = getdb();
        var item = await db.PrivateAgents.FindAsync(_Config.AgentId);
        if (item!.DTExpiresToken < DateTime.Now)
        {

            var ret = await _HC.GetFromJsonAsync<ResponseAccessToken>($"cgi-bin/gettoken?corpid={_Config.CorpId}&corpsecret={item.Secret}");
            ret.Valid();
            item.Token = ret!.access_token;
            item.DTExpiresToken = DateTime.Now.AddSeconds(ret.expires_in);
            await db.SaveChangesAsync();
        }
        return item.Token;

    }
    private WXDbContext getdb() => _ServiceProvider.CreateScope().ServiceProvider.GetRequiredService<WXDbContext>();
}
